interface FileInfo {
  path: string;
  name: string;
  size: number;
  mtime: number;
}

interface FileListenerOptions {
  directoryPath: string;
  interval?: number;
  autoUpload?: boolean;
  uploadManager?: UploadManager;
  onNewFile?: (file: FileInfo) => void;
  onError?: (error: Error) => void;
}

export class FileListener {
  private directoryPath: string;
  private interval: number;
  private autoUpload: boolean;
  private uploadManager?: UploadManager;
  private onNewFile?: (file: FileInfo) => void;
  private onError?: (error: Error) => void;
  private processedFiles: Set<string> = new Set();
  private intervalId: NodeJS.Timeout | null = null;
  private isRunning: boolean = false;
  private fileSizes: Map<string, { size: number; lastCheck: number; checkCount: number }> = new Map();

  constructor(options: FileListenerOptions) {
    this.directoryPath = options.directoryPath;
    this.interval = options.interval || 500;
    this.autoUpload = options.autoUpload || false;
    this.uploadManager = options.uploadManager;
    this.onNewFile = options.onNewFile;
    this.onError = options.onError;
  }

  async start(): Promise<void> {
    if (this.isRunning) {
      console.log('文件监听器已在运行');
      return;
    }

    console.log(`🎯 启动文件监听器: ${this.directoryPath} (间隔: ${this.interval}ms)`);
    
    try {
      // 首次扫描，建立初始文件列表（不上传已有文件）
      await this.buildInitialFileList();
      
      // 开始定时扫描
      this.intervalId = setInterval(() => {
        this.scanDirectory().catch(error => {
          console.error('文件扫描失败:', error);
          this.onError?.(error);
        });
      }, this.interval);
      
      this.isRunning = true;
      console.log('✅ 文件监听器已启动');
      console.log(`📝 已建立初始文件列表，现有 ${this.processedFiles.size} 个文件将被跳过`);
    } catch (error) {
      console.error('启动文件监听器失败:', error);
      this.onError?.(error as Error);
      throw error;
    }
  }

  stop(): void {
    if (!this.isRunning) {
      console.log('文件监听器未运行');
      return;
    }

    console.log('⏹️ 停止文件监听器');
    
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = null;
    }
    
    // 清理所有文件大小记录
    const fileSizesCount = this.fileSizes.size;
    this.fileSizes.clear();
    if (fileSizesCount > 0) {
      console.log(`🧹 清理了 ${fileSizesCount} 个文件大小记录`);
    }
    
    this.isRunning = false;
    console.log('✅ 文件监听器已停止');
  }

  private async scanDirectory(): Promise<void> {
    try {
      if (!window.electronAPI) {
        throw new Error('electronAPI 不可用');
      }

      // 读取目录文件列表
      const files = await window.electronAPI.readdir(this.directoryPath);
      let newFileCount = 0;
      
      for (const fileName of files) {
        const filePath = `${this.directoryPath}/${fileName}`;
        
        // 跳过已处理的文件
        if (this.processedFiles.has(filePath)) {
          continue;
        }

        try {
          // 获取文件状态
          const stats = await window.electronAPI.stat(filePath);
          
          // 检查是否为文件（不是目录）
          if (!stats.isFile) {
            continue;
          }
          
          // 检查文件大小（跳过空文件）
          if (stats.size === 0) {
            continue;
          }
          
          // 检查文件扩展名（只处理图片文件）
          if (!this.isImageFile(fileName)) {
            continue;
          }
          
          // 跳过系统文件和隐藏文件
          if (this.isSystemFile(fileName)) {
            continue;
          }
          
          // 文件大小稳定性检查 - 防止相机拍摄时重复上传
          const now = Date.now();
          const fileRecord = this.fileSizes.get(filePath);
          
          if (fileRecord) {
            // 文件已记录，检查大小是否稳定
            if (fileRecord.size === stats.size) {
              // 大小没有变化，增加检查计数
              fileRecord.checkCount++;
              fileRecord.lastCheck = now;
              
              // 连续3次大小不变，才认为是完整文件
              if (fileRecord.checkCount >= 3) {
                // 这是稳定的新文件！
                newFileCount++;
                
                // 创建文件信息对象
                const fileInfo: FileInfo = {
                  path: filePath,
                  name: fileName,
                  size: stats.size,
                  mtime: stats.mtime
                };

                // 添加到已处理列表
                this.processedFiles.add(filePath);
                // 从大小记录中移除
                this.fileSizes.delete(filePath);
                
                // 触发新文件回调
                console.log(`🆕 发现稳定的新图片: ${fileName} (${this.formatFileSize(stats.size)})`);
                this.onNewFile?.(fileInfo);
                
                // 自动上传功能
                if (this.autoUpload && this.uploadManager) {
                  console.log(`🔄 自动添加到上传队列: ${fileName}`);
                  const taskId = this.uploadManager.addUploadTask(fileInfo);
                  console.log(`📝 上传任务ID: ${taskId}`);
                }
              } else {
                console.log(`⏳ 文件大小检查 ${fileRecord.checkCount}/3: ${fileName}`);
              }
            } else {
              // 大小发生变化，重置检查计数
              console.log(`📊 文件大小变化: ${fileName} ${fileRecord.size} -> ${stats.size}`);
              fileRecord.size = stats.size;
              fileRecord.checkCount = 1;
              fileRecord.lastCheck = now;
            }
          } else {
            // 首次检测到文件，记录大小
            console.log(`🔍 首次检测文件: ${fileName} (${this.formatFileSize(stats.size)})`);
            this.fileSizes.set(filePath, {
              size: stats.size,
              lastCheck: now,
              checkCount: 1
            });
          }

        } catch (error) {
          console.warn(`无法获取文件状态: ${filePath}`, error);
        }
      }

      // 如果有新文件，输出汇总
      if (newFileCount > 0) {
        console.log(`📊 本次扫描发现 ${newFileCount} 个新文件`);
      }

      // 清理内存，防止内存泄漏
      if (this.processedFiles.size > 1000) {
        const oldestFiles = Array.from(this.processedFiles).slice(0, 200);
        oldestFiles.forEach(file => this.processedFiles.delete(file));
        console.log(`🧹 清理了 ${oldestFiles.length} 个已处理文件记录`);
      }

      // 清理过期的文件大小记录（防止内存泄漏）
      const now = Date.now();
      const expiredFiles: string[] = [];
      this.fileSizes.forEach((record, filePath) => {
        // 超过5分钟没有更新的记录，清理掉
        if (now - record.lastCheck > 5 * 60 * 1000) {
          expiredFiles.push(filePath);
        }
      });
      
      expiredFiles.forEach(filePath => {
        this.fileSizes.delete(filePath);
        console.log(`🧹 清理过期的文件大小记录: ${filePath.split('/').pop()}`);
      });
      
      if (expiredFiles.length > 0) {
        console.log(`🧹 总共清理了 ${expiredFiles.length} 个过期的文件大小记录`);
      }

    } catch (error) {
      console.error('扫描目录失败:', error);
      this.onError?.(error as Error);
    }
  }

  private formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  }

  // 获取已处理的文件数量
  getProcessedCount(): number {
    return this.processedFiles.size;
  }

  // 建立初始文件列表（启动时调用，不上传已有文件）
  private async buildInitialFileList(): Promise<void> {
    try {
      if (!window.electronAPI) {
        throw new Error('electronAPI 不可用');
      }

      // 读取目录文件列表
      const files = await window.electronAPI.readdir(this.directoryPath);
      let initialCount = 0;
      
      for (const fileName of files) {
        const filePath = `${this.directoryPath}/${fileName}`;
        
        try {
          // 获取文件状态
          const stats = await window.electronAPI.stat(filePath);
          
          // 只处理文件（不是目录）
          if (!stats.isFile) {
            continue;
          }
          
          // 检查文件大小（跳过空文件）
          if (stats.size === 0) {
            continue;
          }
          
          // 检查文件扩展名（只处理图片文件）
          if (!this.isImageFile(fileName)) {
            continue;
          }
          
          // 跳过系统文件和隐藏文件
          if (this.isSystemFile(fileName)) {
            continue;
          }
          
          // 添加到已处理列表（标记为"已存在"，不上传）
          this.processedFiles.add(filePath);
          initialCount++;
          
        } catch (error) {
          // 跳过无法获取状态的文件
          continue;
        }
      }

      console.log(`📋 建立初始文件列表完成，发现 ${initialCount} 个现有图片文件`);
      
    } catch (error) {
      console.error('建立初始文件列表失败:', error);
      throw error;
    }
  }

  // 清空已处理文件记录
  clearProcessedFiles(): void {
    const processedCount = this.processedFiles.size;
    const fileSizesCount = this.fileSizes.size;
    
    this.processedFiles.clear();
    this.fileSizes.clear();
    
    console.log('🧹 已清空所有记录:');
    if (processedCount > 0) {
      console.log(`  - 已处理文件记录: ${processedCount} 个`);
    }
    if (fileSizesCount > 0) {
      console.log(`  - 文件大小记录: ${fileSizesCount} 个`);
    }
  }

  // 检查是否正在运行
  isListenerRunning(): boolean {
    return this.isRunning;
  }

  // 检查是否为图片文件
  private isImageFile(fileName: string): boolean {
    const imageExtensions = [
      // 常见图片格式
      'jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'tiff', 'tif',
      'heic', 'heif', 'ico', 'svg',
      // RAW格式
      'arw', 'cr2', 'cr3', 'nef', 'orf', 'rw2', 'pef', 'srw',
      'dng', 'raf', '3fr', 'kdc', 'mos', 'mrw', 'nrw', 'gpr'
    ];
    
    const extension = fileName.toLowerCase().split('.').pop();
    return extension ? imageExtensions.includes(extension) : false;
  }

  // 检查是否为系统文件
  private isSystemFile(fileName: string): boolean {
    const systemFilePatterns = [
      // macOS系统文件
      '.DS_Store', '._', '.localized',
      // Windows系统文件
      'Thumbs.db', 'desktop.ini',
      // 隐藏文件（以点开头）
      '^[.]',
      // 系统目录
      'Photos Library.photoslibrary',
      'iPhoto Library.photolibrary',
      'Aperture Library.aplibrary'
    ];
    
    return systemFilePatterns.some(pattern => {
      if (pattern.startsWith('^')) {
        return new RegExp(pattern).test(fileName);
      }
      return fileName.includes(pattern) || fileName.toLowerCase().startsWith(pattern.toLowerCase());
    });
  }
}